package com.zhixianggou.caibaobox.user.shiro.redis;


import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Set;

public class RedisManager {
    private String host = "localhost";

    private int port = 6379;

    private int expire = 300;

    private int timeout = 5000;

    private String password = null;

    private static JedisPool jedisPool = null;

    public void init() {
        if (jedisPool == null) {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxWaitMillis(3000L);
            config.setMaxIdle(200);
            if (this.password != null && !"".equals(this.password)) {
                jedisPool = new JedisPool((GenericObjectPoolConfig)config, this.host, this.port, this.timeout, this.password);
            } else if (this.timeout != 0) {
                jedisPool = new JedisPool((GenericObjectPoolConfig)config, this.host, this.port, this.timeout);
            } else {
                jedisPool = new JedisPool((GenericObjectPoolConfig)config, this.host, this.port);
            }
        }
    }

    public byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis = jedisPool.getResource();
        try {
            value = jedis.get(key);
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
        return value;
    }

    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
        return value;
    }

    public byte[] set(byte[] key, byte[] value, int expire) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
        return value;
    }

    public void del(byte[] key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
    }

    public void flushDB() {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.flushDB();
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
    }

    public Long dbSize() {
        Long dbSize = Long.valueOf(0L);
        Jedis jedis = jedisPool.getResource();
        try {
            dbSize = jedis.dbSize();
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
        return dbSize;
    }

    public Set<byte[]> keys(String pattern) {
        Set<byte[]> keys = null;
        Jedis jedis = jedisPool.getResource();
        try {
            keys = jedis.keys(pattern.getBytes());
        } finally {
//            jedisPool.returnResource(jedis);
            closeJedis(jedis);
        }
        return keys;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return this.port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getExpire() {
        return this.expire;
    }

    public void setExpire(int expire) {
        this.expire = expire;
    }

    public int getTimeout() {
        return this.timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    public void closeJedis( Jedis jedis ) {
        try {
            if ( jedis != null ) {
                if ( jedis != null ) {
                    jedis.close();
                }
            }
        } catch (Exception e) {
            closeBrokenResource( jedis );
        }
    }

    /**
     * Return jedis connection to the pool, call different return methods depends on whether the connection is broken
     */
    public void closeBrokenResource( Jedis jedis ) {
        try {
            jedisPool.returnBrokenResource( jedis );
        } catch ( Exception e ) {
            destroyJedis( jedis );
        }
    }
    /**
     * 在 Jedis Pool 以外强行销毁 Jedis
     */
    public static void destroyJedis( Jedis jedis ) {
        if ( jedis != null ) {
            try {
                jedis.quit();
            } catch ( Exception e ) {
                //e.printStackTrace();
            }

            try {
                jedis.disconnect();
            } catch ( Exception e ) {
                //e.printStackTrace();
            }
        }
    }
}
